<template>
  <div class="set-params" @click="($event) => $event.stopPropagation()">
    <!--  body  -->
    <div class="description">
      <template v-if="selectNode.data.input.length >= 2">
        <!-- 关联关系 union unionall -->
        <a-radio-group v-model="mod" class="mode-radio-group">
          <a-radio :value="1" class="mode-radio">UNION</a-radio>
          <a-radio :value="2" class="mode-radio">UNION ALL</a-radio>
        </a-radio-group>
        <!-- 表名 -->
        <div class="table-name-tips">
          <div class="table-name table-name-left">
            <div class="name-width">
              <a-tooltip placement="top">
                <template slot="title">
                  <span>
                    节点名称：{{ selectNode.data.input[0].nodeName }}
                    <br />
                    表名：{{ selectNode.data.input[0].tableName }}
                  </span>
                </template>
                <span class="name-text">
                  {{ selectNode.data.input[0].nodeName }}
                </span>
              </a-tooltip>
            </div>
          </div>
          <div class="table-name table-name-right">
            <div class="name-width">
              <a-tooltip placement="top">
                <template slot="title">
                  <span>
                    节点名称：{{ selectNode.data.input[1].nodeName }}
                    <br />
                    表名：{{ selectNode.data.input[1].tableName }}
                  </span>
                </template>
                <span class="name-text">
                  {{ selectNode.data.input[1].nodeName }}
                </span>
              </a-tooltip>
            </div>
          </div>
        </div>
        <!-- union -->

        <div
          v-if="
            selectNode.data.input.length > 0 &&
            left.length > 0 &&
            right.length > 0
          "
          class="incidence-all"
        >
          <!-- 左表 节点 data中input字段中第一张表 -->
          <div class="incidence-all-left incidence-left-right">
            <div
              v-for="(leftItem, idx) in left"
              :key="'left' + idx"
              class="incidence-item-column"
            >
              <a-select
                v-model="left[idx]"
                :filter-option="filterOption"
                placeholder="请选择列"
                class="incidence-column-select"
                size="small"
                show-search
                option-filter-prop="children"
                @change="valueChange($event, 'left', idx)"
              >
                <a-select-option
                  v-for="(column1, index) in attributeList.left[idx]"
                  :key="'column1' + index"
                  :title="column1"
                  :value="column1"
                  >{{ column1 }}</a-select-option
                >
              </a-select>
              <div class="incidence-line"></div>
            </div>
          </div>
          <!-- 右表 节点 data中input字段中第二张表 -->
          <div class="incidence-all-right incidence-left-right">
            <div
              v-for="(rightItem, idx) in right"
              :key="'right' + idx"
              class="incidence-item-column"
            >
              <a-select
                v-model="right[idx]"
                :filter-option="filterOption"
                placeholder="请选择列"
                class="incidence-column-select"
                size="small"
                show-search
                option-filter-prop="children"
                @change="valueChange($event, 'right', idx)"
              >
                <a-select-option
                  v-for="(column2, index) in attributeList.right[idx]"
                  :key="'column2' + index"
                  :title="column2"
                  :value="column2"
                  >{{ column2 }}</a-select-option
                >
              </a-select>
              <span class="delete-icon" @click="deleteIncidence(idx)">
                <a-icon-font type="iconicon-beifen5" />
              </span>
            </div>
          </div>
        </div>
        <div v-else class="no-incidence">-- 暂无关联关系，请添加关联 --</div>
        <!--  添加关联关系 btn  -->
        <div
          v-if="selectNode.data.input.length > 0"
          class="add-incidence-relation"
          @click="addIncidenceRelation"
        >
          <a-icon type="plus" />添加关联
        </div>
      </template>
      <div v-else class="set-params-warning">
        -- 该节点需要添加两个父节点 ! --
      </div>

      <!-- relation recommendation bar chart -->
      <div class="module-title">推荐联接子句:</div>
      <div class="auto-union-recommend">
        <div class="legend-color">
          <span class="header-score-legend">字段名推荐</span>
          <span class="value-score-legend">字段值推荐</span>
        </div>
        <div class="recommend-clause">
          <template v-for="(clause, index) in autoUnionRecommendation">
            <div
              v-if="index < 20 && isShow(clause)"
              :key="index"
              class="clause-item"
            >
              <!-- 推荐的字句 -->
              <div class="clause-text">
                <span
                  class="clause-field clause-field-left"
                  :style="{ color: leftColor }"
                  :title="clause.leftHeaderName"
                  >{{ clause.leftHeaderName }}</span
                >
                <span class="relation">=</span>
                <span
                  class="clause-field clause-field-right"
                  :style="{ color: rightColor }"
                  :title="clause.rightHeaderName"
                  >{{ clause.rightHeaderName }}</span
                >
              </div>
              <popover-coefficient-bar
                :score="clause.score"
                :header-score="clause.headerScore"
                :value-score="clause.valueScore"
              />
              <a-icon-font
                class="add-recommend-clause"
                type="iconzengjia"
                @click="addRecommendRelation(clause)"
              />
            </div>
          </template>
        </div>
      </div>
    </div>

    <!--  footer  -->
    <div class="footer-buttons">
      <div class="btn import-btn" @click="confirm">
        {{ buttonText.CONFIRM }}
      </div>
      <div class="btn cancel-btn" @click="cancelChange">
        {{ buttonText.CANCEL }}
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Watch } from 'vue-property-decorator'
import DataViewStore from '@/store/modules/dataview'
import { cloneDeep } from 'lodash'
import { RecommendClause } from '@/components/studio/data/set-params/auto-join/interface-auto-join'
// 推荐的关联关系条形图
import PopoverCoefficientBar from '@/components/studio/data/set-params/auto-join/PopoverCoefficientBar.vue'
import {
  OperatorGroupIconBackGround,
  DataIcon,
} from '@/components/studio/data/graph-compoments/node-icon-util'
import { buttonText } from '@/components/studio/data/set-params/constant'

@Component({
  components: {
    PopoverCoefficientBar,
  },
})
export default class AutoUnion extends Vue {
  public mod = 1
  public left: Array<string> = []
  public right: Array<string> = []
  // 可选属性列表
  private attributeList: any = {
    left: [],
    right: [],
  }
  public autoUnionRecommendation: RecommendClause[] = [] // 推荐关联关系列表

  public buttonText: any = buttonText

  private get selectNode() {
    return DataViewStore.selectNode
  }

  // 监听激活的节点
  @Watch('selectNode', { deep: true })
  private changeSelectNode(selectNode: any) {
    if (selectNode) {
      this.initSet()
    }
  }

  public created() {
    this.initSet()
  }

  public initSet() {
    // 父节点数量小于2，直接返回
    if (this.selectNode.data.input.length < 2) {
      this.autoUnionRecommendation = []
      return
    }

    // 推荐的关联关系列表
    this.autoUnionRecommendation = cloneDeep(
      this.selectNode.data.autoUnionRecommendation
    )

    this.mod = cloneDeep(this.selectNode.data.mod)
    this.left = cloneDeep(this.selectNode.data.left)
    this.right = cloneDeep(this.selectNode.data.right)

    // 自动填充score > 1的子句
    if (
      this.selectNode.data.left.length === 0 &&
      this.autoUnionRecommendation
    ) {
      this.autoUnionRecommendation.forEach((clause: any) => {
        if (clause.score >= 1) {
          this.left.push(clause.leftHeaderName)
          this.right.push(clause.rightHeaderName)
        }
      })
    }

    // 可选属性列表
    this.left.forEach(() => {
      this.attributeList.left.push(this.selectNode.data.input[0].tableCols)
      this.attributeList.right.push(this.selectNode.data.input[1].tableCols)
    })

    const index1 = this.selectNode?.data?.input[0]?.tableCols?.findIndex(
      (item: any) => item === '_record_id_'
    )
    const index2 = this.selectNode?.data?.input[1]?.tableCols?.findIndex(
      (item: any) => item === '_record_id_'
    )
    if (index1 > -1 && index2 > -1) {
      this.selectNode.data?.input[0].tableCols.splice(index1, 1)
      this.selectNode.data?.input[1].tableCols.splice(index2, 1)
    }
  }

  // 用户选中的关联关系
  private get unionRelationList() {
    return this.left.map((leftItem: string, index: number) => {
      return [leftItem, this.right[index]]
    })
  }

  // 用户选中关联关系属性, 修改推荐排序
  public valueChange($event: any, table: string, idx: number) {
    const scoreMap = new Map()
    if (table === 'left') {
      this.attributeList.right[idx].forEach((attributeName: string) => {
        scoreMap.set(attributeName, 0)
      })
      this.autoUnionRecommendation
        .filter((clause: any) => clause.leftHeaderName === String($event))
        .forEach((clause: any) => {
          scoreMap.set(clause.rightHeaderName, clause.score)
        })
      this.attributeList.right[idx] = [...scoreMap]
        .sort((a, b) => b[1] - a[1])
        .map((item) => item[0])
    } else if (table === 'right') {
      this.attributeList.left[idx].forEach((attributeName: string) => {
        scoreMap.set(attributeName, 0)
      })
      this.autoUnionRecommendation
        .filter((clause: any) => clause.rightHeaderName === String($event))
        .forEach((clause: any) => {
          scoreMap.set(clause.leftHeaderName, clause.score)
        })
      this.attributeList.left[idx] = [...scoreMap]
        .sort((a, b) => b[1] - a[1])
        .map((item) => item[0])
    }
  }

  // 节点颜色
  public get leftColor() {
    if (typeof this.selectNode.data.input[0]?.subType === 'number') {
      return OperatorGroupIconBackGround[this.selectNode.data.input[0]?.subType]
        .color
    }
    // @ts-ignore
    return DataIcon.color
  }
  public get rightColor() {
    if (typeof this.selectNode.data.input[1]?.subType === 'number') {
      return OperatorGroupIconBackGround[this.selectNode.data.input[1]?.subType]
        .color
    }
    // @ts-ignore
    return DataIcon.color
  }

  // 列选项搜索功能
  public filterOption(input: any, option: any) {
    return option.componentOptions.children[0].text
      .toLowerCase()
      .includes(input.toLowerCase())
  }

  // 推荐的关联关系是否展示（已使用的推荐 不展示）
  public isShow(clause: any) {
    return (
      this.unionRelationList.filter((unionRelation: any) => {
        return (
          unionRelation[0] === clause.leftHeaderName &&
          unionRelation[1] === clause.rightHeaderName
        )
      }).length === 0
    )
  }

  // 手动添加关联关系
  public addIncidenceRelation() {
    this.left.push('')
    this.right.push('')
    this.attributeList.left.push(this.selectNode.data.input[0].tableCols)
    this.attributeList.right.push(this.selectNode.data.input[1].tableCols)
  }

  // 添加推荐关联关系
  public addRecommendRelation(clause: RecommendClause) {
    this.left.push(clause.leftHeaderName)
    this.right.push(clause.rightHeaderName)
    this.attributeList.left.push(this.selectNode.data.input[0].tableCols)
    this.attributeList.right.push(this.selectNode.data.input[1].tableCols)
  }

  // 删除关联关系
  public deleteIncidence(idx: number) {
    this.left.splice(idx, 1)
    this.right.splice(idx, 1)
  }

  // 确认修改
  public confirm() {
    let status = true
    this.left.forEach((item: any) => {
      if (item === '') {
        status = false
      }
    })
    this.right.forEach((item: any) => {
      if (item === '') {
        status = false
      }
    })
    if (status && this.left.length !== 0) {
      this.$emit('confirm', {
        mod: this.mod,
        left: this.left,
        right: this.right,
      })
    } else {
      this.$message.warning('请填写关联条件')
    }
  }

  // 重置修改
  public cancelChange() {
    this.initSet()
  }
}
</script>

<style lang="less" scoped>
@import '@/components/studio/data/set-params/setParams';
/* 模式 */
.mode-radio-group {
  font-size: 12px;
  margin-bottom: 12px;
}

/* 表名 */
.table-name-tips {
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  margin-bottom: 12px;
  width: 100%;

  .table-name {
    display: flex;

    .name-width {
      width: 140px;

      .name-text {
        color: #1e49f8;
        display: inline-block;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        width: 100%;
      }
    }
  }

  .table-name-left {
    width: 55%;
  }

  .table-name-right {
    width: 45%;
  }
}
/* 关联关系 */
.incidence-all {
  display: flex;
  justify-content: space-between;
  width: 100%;

  /* 左 */
  .incidence-all-left {
    padding-right: 24px;
    width: 55%;

    /* 线 */
    .incidence-line {
      border-bottom: 1px solid #d9d9d9;
      height: 1px;
      margin-left: 24px;
      width: calc(100% - 164px);
    }
  }

  .incidence-all-right {
    width: 45%;
  }

  /* 左右 右 */
  .incidence-left-right {
    display: flex;
    flex-direction: column;

    /* 单选框 */
    .incidence-item-column {
      align-items: center;
      display: flex;
      margin-bottom: 8px;

      .incidence-column-select {
        height: 24px;
        width: 140px;
      }

      /* delete icon */
      .delete-icon {
        cursor: pointer;
        display: inline-block;
        height: 24px;
        line-height: 24px;
        padding-left: 12px;
        width: 28px;
      }
    }
  }
}

.no-incidence {
  color: #888;
  font-style: italic;
  height: 40px;
  line-height: 40px;
  margin-bottom: 12px;
  text-align: center;
}

.set-params-warning {
  color: #888;
  font-size: 12px;
  font-style: italic;
  padding: 15px 10px 0;
  text-align: center;
}

/* 添加 */
.add-incidence-relation {
  border: 1px solid #e9e9e9;
  color: #6973ff;
  cursor: pointer;
  height: 32px;
  line-height: 32px;
  text-align: center;
  width: 100%;
}

.module-title {
  color: #5d637e;
  display: flex;
  font-size: 12px;
  font-weight: 600;
  height: 17px;
  letter-spacing: 1px;
  line-height: 17px;
  margin-bottom: 6px;
  margin-top: 6px;

  .title-text {
    color: #9b9da8;
    font-size: 12px;
    font-weight: 500;
  }
}

// 推荐的关联关系
.auto-union-recommend {
  overflow: hidden;
  width: 100%;

  // 推荐的 bar 图例
  .legend-color {
    display: flex;
    justify-content: center;

    .header-score-legend {
      margin: 0 8px 0 18px;
      position: relative;

      &::before {
        background-color: #8289dd;
        content: '';
        height: 8px;
        left: -14px;
        position: absolute;
        top: 4px;
        width: 10px;
      }
    }

    .value-score-legend {
      margin: 0 8px 0 18px;
      position: relative;

      &::before {
        background-color: #ced0ed;
        content: '';
        height: 8px;
        left: -14px;
        position: absolute;
        top: 4px;
        width: 10px;
      }
    }
  }

  // 推荐的子句
  .recommend-clause {
    width: 100%;

    .clause-item {
      align-items: center;
      cursor: pointer;
      display: flex;
      height: 22px;
      justify-content: space-between;
      margin: 2px 0;

      /* 连接关系 */
      .clause-text {
        display: flex;
        justify-content: space-between;
        width: 150px;

        .clause-field {
          overflow: hidden;
          text-align: right;
          text-overflow: ellipsis;
          white-space: nowrap;
          width: 40%;
        }

        .clause-field-right {
          text-align: left;
        }

        .relation {
          color: #5d637e;
          text-align: center;
          width: 20%;
        }
      }

      /* 添加 icon */
      .add-recommend-clause {
        font-size: 16px;
        margin-left: 6px;
        opacity: 0;
      }

      &:hover {
        background-color: #eaeaea;

        .add-recommend-clause {
          opacity: 1;
        }
      }
    }
  }

  .recommend-coefficient {
    z-index: 10;
  }
}
</style>
